﻿using SoldiHive.Infrustructure.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;

namespace SoldiHive.Model
{
	[Serializable]
	public class Company : MarketEntity, IFormattable
	{
		private const double billion = 1000000000;

		private string ticker;
		public string Ticker 
		{
			get 
			{
				return this.ticker;
			}
			set
			{
				this.ticker = value.ToUpper();
				this.Key = this.ticker;
			}
		}

		public override string Name { get; set; }
		public double Cap { get; set; }
		public double Price { get; set; }
		public Sector Sector { get; set; }
		public Industry Industry { get; set; }
		public SubIndustry SubIndustry { get; set; }

		public Company(string ticker)
			:base(string.Empty)
		{
			this.Ticker = ticker.ToUpper();
		}

		public Company(string ticker, double cap)
			: base(string.Empty)
		{
			this.Ticker = ticker;
			this.Cap = cap;
		}

		public Company(string ticker, string name, double cap)
			: base(name)
		{
			this.Ticker = ticker;
			this.Name = name;
			this.Cap = cap;
		}

		public Company(string ticker, string name, double cap, Sector sector, Industry industry, SubIndustry subIndustry)
			:base(name)
		{
			this.Ticker = ticker;
			this.Name = name;
			this.Cap = cap;
			this.Sector = sector;
			this.Industry = industry;
			this.SubIndustry = subIndustry;
		}

		public override string ToString()
		{
			return this.ToString(string.Empty, null);
		}

		public override bool Equals(object obj)
		{
			return base.Equals(obj);
		}

		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		public static bool operator ==(Company left, Company right)
		{
			if ((object)left == null)
			{
				return Company.Equals(left, right);
			}

			return left.Equals(right); 
		}

		public static bool operator !=(Company left, Company right)
		{
			return !(left == right);
		}

		public string ToString(string format, IFormatProvider formatProvider)
		{
			if (string.IsNullOrEmpty(format))
			{
				format = "Ticker,Cap";
			}

			var properyNames = format.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
				.Select(properyName => properyName.Trim());

			var values = new List<string>();
			foreach (var propertyName in properyNames)
			{
				var valueStr = string.Empty;
				if (string.Equals("Cap", propertyName, StringComparison.InvariantCultureIgnoreCase))
				{
					valueStr = string.Format("${0:0.##}B", this.Cap / Company.billion);
				}
				else
				{
					var value = this.GetProperyValue<object>(propertyName);
					if (value != null)
					{
						valueStr = string.Format("{0}", value);

						if (string.Equals("Ticker", propertyName, StringComparison.InvariantCultureIgnoreCase))
						{
							valueStr = valueStr.Align(4);
						}
						else if (!string.IsNullOrEmpty(valueStr) &&
								 !string.Equals("Name", propertyName, StringComparison.InvariantCultureIgnoreCase))
						{
							valueStr = string.Format("'{0}'", valueStr);
						}
					}
				}

				if (string.IsNullOrEmpty(valueStr))
				{
					valueStr = "N/A";
				}

				values.Add(valueStr);
			}

			var companyString = string.Join(" ", values);

			return companyString;
		}
	}
}
